﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Odelle.BlueForest
{
    public partial class FilterItem : UserControl
    {
        public event System.EventHandler ValueChanged = delegate(Object s, EventArgs e) { };
        public event System.EventHandler FilterNameChanged = delegate(Object s, EventArgs e) { };

        Odelle.Utils.ClassInfoReader Cinfo = new Utils.ClassInfoReader(typeof(Odelle.WoWArmory.Data.CharacterData));
        string[] names;
        public FilterItem()
        {
            InitializeComponent();
            flowLayoutPanel1.Dock = DockStyle.Fill;
            this.Operator = "=";
            Repaint();
            Clear();

            cmbTitle.Items.Clear();
            names= Cinfo.GetNames();
            cmbTitle.Items.Add("---");
            for (int i = 0; i < names.Length; ++i)
            {
                cmbTitle.Items.Add(Cinfo.GetInfo(names[i]).Title);
            }
        }

        private void FilterItem_Resize(object sender, EventArgs e)
        {
            Repaint();
        }
        private void flowLayoutPanel1_SizeChanged(object sender, EventArgs e)
        {
            Repaint();
        }

        public void Repaint()
        {
            flowLayoutPanel1.Refresh();

            this.Height = cmbTitle.Height + flowLayoutPanel1.Padding.Top + flowLayoutPanel1.Padding.Bottom;
            lblTitle.Height = cmbTitle.Height - lblTitle.Margin.Top;
            lblTitle.Width = _titleWidth;
            cmbTitle.Width = _titleWidth;

            if (_isNameFixed)
            {
                lblTitle.Visible = true;
                cmbTitle.Visible = false;
            }
            else
            {
                cmbTitle.Visible = true;
                lblTitle.Visible = false;
            }

            if (_isNumber)
            {
                cmbOperator.Visible = true;
                cmbValue.Width = this.Width - cmbTitle.Width - cmbTitle.Margin.Right - cmbOperator.Width - cmbOperator.Margin.Right - flowLayoutPanel1.Padding.Left - flowLayoutPanel1.Padding.Right -1;
            }
            else
            {
                cmbOperator.Visible = false;
                cmbValue.Width = this.Width - cmbTitle.Width - cmbTitle.Margin.Right - flowLayoutPanel1.Padding.Left - flowLayoutPanel1.Padding.Right - 1;
            }
        }

        private bool _isNumber = false;
        public bool IsNumber
        {
            private set
            {
                _isNumber = value;

                if (_isDropDownList && !(_isNumber))
                    cmbValue.DropDownStyle = ComboBoxStyle.DropDownList;
                else
                    cmbValue.DropDownStyle = ComboBoxStyle.DropDown;

                Repaint();
            }
            get
            { return _isNumber; }
        }

        int _titleWidth = 150;
        public int TitleWidth
        {
            set
            {
                if (value >= 30)
                {
                    _titleWidth = value;
                    Repaint();
                }
            }
            get
            { return _titleWidth; }
        }

        private bool _isNameFixed = false;
        public bool IsNameFixed
        {
            set
            {
                _isNameFixed = value;
                Repaint();
            }
            get
            { return _isNameFixed; }
        }

        private bool _isDropDownList = true;
        public bool IsDropdownList
        {
            set
            {
                _isDropDownList = value;

                if (_isDropDownList && !(_isNumber))
                    cmbValue.DropDownStyle = ComboBoxStyle.DropDownList;
                else
                    cmbValue.DropDownStyle = ComboBoxStyle.DropDown;
            }
            get
            {
                return _isDropDownList;
            }
        }

        private bool _hasError = false;
        public bool HasError
        {
            set
            {
                _hasError = value;

                if (_hasError)
                {
                    this.BackColor = Color.Red;
                    cmbTitle.ForeColor = Color.Red;
                }
                else
                {
                    this.BackColor = SystemColors.Control;
                    cmbTitle.ForeColor = SystemColors.WindowText;
                }   
            }
            get 
            { return _hasError; }
                 
        }

        private string _filterName = "";
        public string FilterName
        {
            get
            {
                return _filterName;
            }
            set
            {
                if (names == null)
                {
                }
                else if (value == "")
                {
                    _filterName = "";
                    cmbTitle.SelectedIndex = 0;
                    lblTitle.Text = cmbTitle.Text;

                    this.IsNumber = false;

                    if (FilterNameChanged != null)
                        FilterNameChanged(this, EventArgs.Empty);

                    this.Clear();
                }
                else if (names.Contains<string>(value))
                {
                    _filterName = value;

                    string title = Cinfo.GetInfo(_filterName).Title;
                    lblTitle.Text = title;
                    cmbTitle.Text = title;

                    this.IsNumber = Cinfo.GetInfo(value).IsNumber;

                    if (FilterNameChanged != null)
                        FilterNameChanged(this, null);

                    this.Clear();
                }
                else
                {
                }
            }
        }

        public string Operator
        {
            set
            { cmbOperator.Text = value; }
            get
            { return cmbOperator.Text; }
        }

        public string Value
        {
            set
            {
                if (this.IsDropdownList && !this.IsNumber)
                {
                    if (cmbValue.Items.Contains(value))
                        cmbValue.Text = value;
                    else
                        cmbValue.SelectedIndex = 0;
                }
                else
                {
                    cmbValue.Text = value;
                }
            }
            get
            { return cmbValue.Text; }
        }

        public void Clear()
        {
            //cmbOperator.SelectedIndex = 0;

            cmbValue.Items.Clear();
            cmbValue.Items.Add("*");
            cmbValue.SelectedIndex = 0;
        }

        public void AddItem(string value)
        {
            if (!cmbValue.Items.Contains(value))
                cmbValue.Items.Add(value);
        }

        public void AddRange(string[] values)
        {
            if (values.Length > 0)
                cmbValue.Items.AddRange(values);
        }

        public string FilterValue
        {
            get
            {
                if (_isNumber)
                    return cmbOperator.Text + cmbValue.Text;
                else
                    return cmbValue.Text;
            }
        }

        public string FilterEntry
        {
            get
            {
                if (_filterName == "")
                    return "";

                if (cmbValue.Text == "*")
                    return "";

                if (this.HasError)
                    return "";

                return this.FilterName + WoWArmory.Data.CharacterQuery.QueryDelimiter.ToString() + this.FilterValue;
            }
        }

        private void cmbOperator_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (_isNumber)
            {
                if (ValueChanged != null)
                    ValueChanged(this, EventArgs.Empty);
            }
        }

        private void cmbValue_SelectedIndexChanged(object sender, EventArgs e)
        {
            ValidateValue();

            if (ValueChanged != null)
                ValueChanged(this, EventArgs.Empty);
        }

        private void cmbValue_TextChanged(object sender, EventArgs e)
        {
            ValidateValue();
        }

        private void cmbTitle_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbTitle.SelectedIndex == 0)
            {
                _filterName = "";
                this.IsNumber = false;
            }
            else
            {
                _filterName = names[cmbTitle.SelectedIndex - 1];
                lblTitle.Text = cmbTitle.Text;
                this.IsNumber = Cinfo.GetInfo(_filterName).IsNumber;
            }

            if (FilterNameChanged != null)
                FilterNameChanged(this, EventArgs.Empty);

            this.Clear();
        }

        private void ValidateValue()
        {
            bool hasValueError = false;

            if (cmbValue.Text != "" && cmbValue.Text != "*")
            {
                if (Cinfo.GetInfo(_filterName).IsNumber)
                {
                    Type t = Cinfo.GetInfo(_filterName).DataType;

                    if (t == typeof(int))
                    {
                        int val;
                        hasValueError = !(int.TryParse(cmbValue.Text, out val));
                    }
                    else if (t == typeof(long))
                    {
                        long val;
                        hasValueError = !(long.TryParse(cmbValue.Text, out val));
                    }
                    else if (t == typeof(double))
                    {
                        double val;
                        hasValueError = !(double.TryParse(cmbValue.Text, out val));
                    }
                    else if (t == typeof(float))
                    {
                        float val;
                        hasValueError = !(float.TryParse(cmbValue.Text, out val));
                    }
                    else if (t == typeof(DateTime))
                    {
                        DateTime val;
                        hasValueError = !(DateTime.TryParse(cmbValue.Text, out val));
                    }
                }
            }

            if (hasValueError)
            {
                cmbValue.BackColor = Color.Pink;
            }
            else
            {
                cmbValue.BackColor = SystemColors.Window;
            }
            
        }

    }
}
